iT邦幫忙

0

Design Pattern - Factory method(工廠方法),Factory生產Product

  • 分享至 

  • xImage
  •  

工廠方法-Factory method

這應該是大家學design pattern第一個遇到的pattern吧,這個pattern有兩個角色

  • 一個是 Factory
  • 另一個是 Product

簡單說就是透過Factory來生產Product,client只需要告訴Factory,我要一個什麼Product,然後就得到他要的Product了。

架構圖長這樣:
factory-method


範例

我現在要去吃pizza了,所以需要定義:

  • Factory: PizzaStore
  • Product: Pizza

當然都要是AbstractClass 或 interface,不應該把實作內容直接寫在這邊,物件導向語言的其中一個守則:針對介面寫程式,不是針對實踐方法寫程式

宣告Factory

public abstract class PizzaStore {

    public abstract Pizza createPizza(String type); 

    public Pizza orderPizza(String type) { // client只要呼叫這個method就好

        Pizza pizza = createPizza(type);

        pizza.prepare();
        pizza.bake();
        pizza.cut();
        pizza.box();

        return pizza;

    }
}

宣告Product

package com.example.designpattern.creational.factory_method.example2;

public abstract class Pizza {

    String name;
    String dough;
    String sauce;

    // method都不是宣告為abstract,如果subClass不用客製,就不用override
    void prepare() {
        System.out.println("Preparing: " + name + ", " + dough + ", " + sauce );
        System.out.println("Tossing dough...");
    };
    
    void bake() {
        System.out.println("Bake for 25 minutes at 350");
    }
    
    void cut() {
        System.out.println("Cutting pizza into diagonal slices");
    }
    
    void box() {
        System.out.println("Place pizza in official PizzaStore box");
    }
}

有了Factory跟Product後,就可以繼承他們來寫concreteClass了
先寫Factory,NYPizzaStore

package com.example.designpattern.creational.factory_method.example2;

public class NYPizzaStore extends PizzaStore {
    @Override
    public Pizza createPizza(String type) {
        Pizza pizza = null;
        
        // 這間PizzaStore可以生產兩種Pizza
        if("cheese".equals(type)) {
            pizza = new NYCheesePizza();
        } else if ("sausage".equals(type)) {
            pizza = new NYSausagePizza();
        }

        return pizza;
    }

    @Override
    public Pizza orderPizza(String type) {
        return super.orderPizza(type);
    }
}

再來是Product,第一種Product NYCheesePizza

package com.example.designpattern.creational.factory_method.example2;

public class NYCheesePizza extends Pizza {

    String name = "NYCheesePizza";
    String dough = "crispy";
    String sauce = "cheese sauce";

    @Override
    void prepare() {
        System.out.println("Amazing~~~ " + name +" , " + dough + " , " + sauce);
    }
    
    @Override
    void bake() {
        System.out.println("Bake for 15 minutes at 400");
    }
    
    @Override
    void cut() {
        System.out.println("Cutting pizza into 8 slices");
    }

}

第二種Prodcut NYSausaePizze

package com.example.designpattern.creational.factory_method.example2;

public class NYSausagePizza extends Pizza {
   String name = "NY Sausage pizze";
   String dough = "Thick";
   String sauce = "Marinara sauce";

    @Override
    void prepare() {
        System.out.println(name +" , " + dough + " , " + sauce);
    }
}

Client 要來點pizza了

package com.example.designpattern.creational.factory_method.example2;

public class PizzaClient {

    public static void main(String[] args) {
        // 進入NYPizzaStore
        PizzaStore pizzaStore = new NYPizzaStore();
        
        // 我要cheese pizza,啪,cheesePizza
        Pizza cheesePizza = pizzaStore.orderPizza("cheese");

        System.out.println("---------------");
        
        // 我要sausage pizza,啪,sausagePizza
        Pizza sausagePizza = pizzaStore.orderPizza("sausage"); 
    }
    /*
        output:

        Amazing~~~ NYCheesePizza , crispy , cheese sauce
        Bake for 15 minutes at 400
        Cutting pizza into 8 slices
        Place pizza in official PizzaStore box
        
        ---------------
        NY Sausage pizze , Thick , Marinara sauce
        Bake for 25 minutes at 350
        Cutting pizza into diagonal slices
        Place pizza in official PizzaStore box

     */
}



Reference:

https://refactoring.guru/design-patterns/factory-method
https://www.oreilly.com/library/view/head-first-design/0596007124/


圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言